//
//  YTFMDBWithRunTimeManager.m
//  03 - YTRunTimeFMDB
//
//  Created by 余婷 on 16/6/1.
//  Copyright © 2016年 余婷. All rights reserved.
//

#import "YTFMDBWithRunTimeManager.h"
#import "FMDatabase.h"

//使用runtime的方法，需要导入runtime.h文件
#import <objc/runtime.h>

@interface YTFMDBWithRunTimeManager(){

    //数据库对象
    FMDatabase * _db;
}

@end

@implementation YTFMDBWithRunTimeManager

#pragma mark - 初始化
- (instancetype)init{

    if (self = [super init]) {
        
        //打开数据库
        [self openSqlite];
    }
    
    return self;
}

#pragma mark - 打开数据库
- (void)openSqlite{

    //打开数据库
    NSString * path = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/User.db"];
    _db = [[FMDatabase alloc] initWithPath:path];
    
    if ([_db open]) {
        
        NSLog(@"数据库打开成功");
    }else{
        
        NSLog(@"数据库打开失败");
    }
}

#pragma mark - 创建表
- (void)creatTableWithClass:(Class)objcClass{
    
    //========获取类的名字和类的属性名======
    //1.获取类的类名
    //const char *class_getName(Class cls)
    const char * className = class_getName(objcClass);
    NSLog(@"%s", className);
    
    //2.获取所有的属性名
    NSArray * allName = [self getAllPropertyNameWithClass:objcClass];
//    CREATE TABLE IF NOT EXISTS ?(id integer PRIMARY KEY AUTOINCREMENT,?);
    //===============创建表=============
    
    //1.创建sql语句
    //表名
    NSString * tableName = [NSString stringWithUTF8String:className];
    //字段列表
    NSMutableString * mstr = [[NSMutableString alloc] init];
    for (NSString * name in allName) {
        
        [mstr appendFormat:@",%@ text", name];
    }
    
    //拼接sql语句
    NSString * newSql = [NSString stringWithFormat:@"CREATE TABLE IF NOT EXISTS t_%@(id integer PRIMARY KEY AUTOINCREMENT %@);",tableName, mstr];
    
    //2.执行sql语句
    if ([_db executeUpdate:newSql]) {
        
        NSLog(@"创建表成功");
    }else{
    
        NSLog(@"创建表失败");
    }
    
    
    
}

#pragma mark -通过类获取类中的所有的属性名
- (NSArray *)getAllPropertyNameWithClass:(Class)objcClass{
    
    //1.获取类中所有的属性
    //参数1:类
    //参数2:用来获取属性的个数
    unsigned int outcount;
    objc_property_t * proprttyLists = class_copyPropertyList(objcClass, &outcount);
    
    //创建可变数组，用来存储类的属性名
    NSMutableArray * marray = [[NSMutableArray alloc] init];
    
    //遍历获取所有的属性
    for (int i = 0; i < outcount; i++) {
        
        objc_property_t property = proprttyLists[i];
        
        //2.得到属性的名字
        const char * name = property_getName(property);
        
        //将属性名转换成OC字符串，存到数组中
        [marray addObject:[NSString stringWithUTF8String:name]];
        
        //3.获取属性类型
//        const char * attr = property_getAttributes(property);
//        NSLog(@"!!:%s", attr);
        
    }
    
    return marray;
}

#pragma mark =======外部方法=========
#pragma mark - 根据指定key查看记录是否存在
- (BOOL)checkItemIsExistWithClass:(Class)objcClass key:(id)key value:(id)value{

    //类名
    const char * className = class_getName(objcClass);
    
    
    NSString * sql = [NSString stringWithFormat:@"SELECT count(*) FROM t_%s WHERE %@ = %@", className, key, value];
//    SELECT count(*) FROM 表名 WHERE 字段 = 值
    
    FMResultSet * set = [_db executeQuery:sql];
    
    while ([set next]) {
        
        int a = [set intForColumnIndex:0];
        
        if (a > 0) {
            
            return YES;
        }
    }
    
    return NO;
    
}

#pragma mark - 将数据插入到数据库中
//将数据插入到数据库中
- (void)inserObjct:(id)objc{

    //1.创建表
    //对象调用class可以获取到对象的类型
    [self creatTableWithClass:[objc class]];
    
    //2.将数据插入到表中
//    INSERT INTO t_%s (name,sex,age) VALUES ('小明','男','19');
    const char * className = class_getName([objc class]);
    
    //3.获取所有的属性名
    NSArray * perportynames = [self getAllPropertyNameWithClass:[objc class]];
    //4.遍历数组
    //字段列表
    NSMutableString * mkey = [NSMutableString new];
    //值列表
    NSMutableString * mValue = [NSMutableString new];
    
    int  i = 0;
    for (NSString * name in perportynames) {
        
        //根据属性名获取属性的值
        id value = [objc valueForKey:name];
        NSString * valueStr = [NSString stringWithFormat:@"'%@'", value];
        
        //如果是最后一个字段，不用拼接逗号
        if (i == perportynames.count - 1) {
            
            //拼接字段
            [mkey appendString:name];
            
            //拼接值
            [mValue appendString:valueStr];

        }else{
            //拼接字段
            [mkey appendFormat:@"%@,",name];
            //拼接字段
            [mValue appendFormat:@"%@,", valueStr];
        }

        i++;
    }
    
    //拼接sql语句
    NSString * sql = [NSString stringWithFormat:@"INSERT INTO t_%s (%@) VALUES (%@);",className,mkey,mValue];
    
    //执行sql语句
    if ([_db executeUpdate:sql]) {
        NSLog(@"数据插入成功");
    }else{
    
        NSLog(@"数据插入失败");
    }
}

#pragma mark - 获取数据库中的数据
- (NSArray *)getAllData:(Class)objcClass{

    //SELECT * FROM t_%s;
    //1.创建sql语句
    NSString * sql = [NSString stringWithFormat:@"SELECT * FROM t_%s;",class_getName(objcClass)];
    
    //2.执行sql语句
    FMResultSet * set = [_db executeQuery:sql];
    if (set) {
        NSLog(@"查询成功");
        //创建一个可变数组，用来存储返回结果
        NSMutableArray * marray = [NSMutableArray new];
        while ([set next]) {
            
            //创建对象
            id objc = [objcClass new];
            
            for (NSString * name in [self getAllPropertyNameWithClass:objcClass]) {
                
                //拿到了每个属性对应的值
                id value = [set objectForColumnName:name];
                
                //给对象的属性赋值
                [objc setValue:value forKey:name];
            }
            
            //将对象存到数组中
            [marray addObject:objc];
        }
        
        //返回结果
        return marray;
        
    }else{
    
        NSLog(@"查询失败");
        
        return nil;
    }
    
}

- (void)delectItemIsExistWithClass:(Class)objcClass key:(id)key value:(id)value{
    
    const char * classname = class_getName(objcClass);

    NSString * sql = [NSString stringWithFormat:@"DELETE FROM t_%s WHERE %@ = '%@';",classname,key,value];
    
    BOOL ret = [_db executeUpdate:sql];
    
    if (ret) {
        
        NSLog(@"删除成功");
        
    }else{
    
        NSLog(@"删除失败");
    }
    
}

@end
